﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace WiiRegionChanger
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }
        
        //bring filename/path from first form

        public string filenameF2TextBoxValue
        {
            get
            {
                return filenameF2TextBox.Text;
            }
            set
            {
                filenameF2TextBox.Text = value;
            }
        }


        private void Form2_Load(object sender, EventArgs e)
        {
            
            string path = filenameF2TextBox.Text;
            int x;

            //get the image size
            FileInfo fi = new FileInfo(path);
            long wiiIsoSize = fi.Length;
            imageSizeTextBox.Text = wiiIsoSize.ToString();

            //partition numbers
            partNum1TextBox.Text = "0x1";
            partNum2TextBox.Text = "0x2";
            partNum3TextBox.Text = "0x3";
            partNum4TextBox.Text = "0x4";
            partNum5TextBox.Text = "0x5";
            partNum6TextBox.Text = "0x6";


            //1. Get Number of Partitions
            string numParts;
            FileStream fs100 = new FileStream(@path, FileMode.Open, FileAccess.Read);
            long offset100 = fs100.Seek(262144, SeekOrigin.Begin);   // Seek to 262144th byte in the file
            x = 0;
            //read four bytes to get the number of partitions
            while (x <= 3)
            {
                numParts = fs100.ReadByte().ToString("X");
                if (numParts.Length == 1)
                {
                    numParts = "0" + numParts;
                }
                numOfPartTextBox.Text += numParts;
                x++;
            }
            fs100.Close();


            //2. Get partition table offset
            /*get the info at location 40004 & 40006, offset262148 read 4 bytes
             * 0x40004		00 01 00 08  -> 0001 0008 -> 10008 ->binary is 1 00000000 00001000
             * we need to shift left 2, so now we have
             * 100 00000000 00100000 ->  40020h -> 262176d <-offset of partition info
             * 
             * Is the partition an update partition or no?
             * 40020h + 4h = 40024h, read data
             * 0x40024  00 00 00 01  ->00000001-> 1 indicates an update partition / 0 if not
             */

            string pof, pito1;
            FileStream fs101 = new FileStream(@path, FileMode.Open, FileAccess.Read);
            long offset101 = fs101.Seek(262148, SeekOrigin.Begin);   // Seek to 262148 byte in the file

            pof = "";
            pito1 = "";

            x = 0;
            //this loop lets us grab bytes 262148 to 262151
            while (x <= 3)
            {
                
                    pof = fs101.ReadByte().ToString("X");
                    if (pof.Length == 1)
                    {
                        pof = "0" + pof;
                    }

                //this stores the hex value of the offset 262148 + 4bytes
                pito1 += pof; //hex string
                
                x++;

            }
            fs101.Close();

            //this is how we left shift 2 
            string pito1Binary = Convert.ToString(Convert.ToInt32(pito1, 16), 2);
            pito1Binary = pito1Binary + "00";

            //convert from binary back to hex to get the offset 
            string pito1Hex = Convert.ToString(Convert.ToInt32(pito1Binary, 2), 16);

            partTableOffTextBox.Text = "0x" + pito1Hex;
            //put the offset to decimal form for seeking 1st partition info
            int pito1Dec = int.Parse(pito1Hex, System.Globalization.NumberStyles.HexNumber);

            //now we need to get the type of partition, so move up 4 bytes and read that data
            int pito1DecType = pito1Dec + 4;

            string typeOfPartHex, typeOfPartHexAll;
            FileStream fs102 = new FileStream(@path, FileMode.Open, FileAccess.Read);
            long offset102 = fs102.Seek(pito1DecType, SeekOrigin.Begin);   // Seek to 262148 byte in the file
            typeOfPartHex = "";
            typeOfPartHexAll = "";
            x = 0;
            //this loop lets us grab 4 bytes to get the type of partition
            while (x <= 3)
            {
                typeOfPartHex = fs102.ReadByte().ToString("X");
                if (typeOfPartHex.Length == 1)
                {
                    typeOfPartHex = "0" + typeOfPartHex;
                }
                //this stores the hex value of the offset 262148 + 4bytes
                typeOfPartHexAll += typeOfPartHex; //hex string
                //partType1TextBox.Text = typeOfPartHexAll;
                x++;
            }
            fs102.Close();

            //define the partition type
            if (typeOfPartHexAll == "00000001")
            {
                partType1TextBox.Text = "1 (Update)";
            }
            else if (typeOfPartHexAll == "00000000")
            {
                partType1TextBox.Text = "0 (Data)";
            }
            else
            {
                partType1TextBox.Text = "? Unknown -> HEX Value:" + typeOfPartHexAll;
            }

            //3. Get 1st partition offset
            //0x40020		00 01 40 00  ->00014000->10100000000000000->(<<2)
            //->1010000000000000000->(327680d, 0x00050000h)
            string p1offset, p1offsetHex;
            FileStream fs103 = new FileStream(@path, FileMode.Open, FileAccess.Read);
            long offset103 = fs103.Seek(pito1Dec, SeekOrigin.Begin);   // Seek to pito1Dec byte in the file

            p1offset = "";
            p1offsetHex = "";

            x = 0;
            //this loop lets us grab bytes 327680 (4 bytes)
            while (x <= 3)
            {

                p1offset = fs103.ReadByte().ToString("X");
                if (p1offset.Length == 1)
                {
                    p1offset = "0" + p1offset;
                }

                //output the hex value
                p1offsetHex += p1offset;

                x++;

            }
            fs103.Close();


            //this is how we left shift 2 
            string p1offsetBinary = Convert.ToString(Convert.ToInt32(p1offsetHex, 16), 2);
            p1offsetBinary = p1offsetBinary + "00";

            //convert from binary back to hex to get the offset 
            string p1offsetFoundHex = Convert.ToString(Convert.ToInt32(p1offsetBinary, 2), 16);

            po1TextBox.Text = "0x" + p1offsetFoundHex;
            //put the offset to decimal form for seeking ??
            int p1offsetDec = int.Parse(p1offsetFoundHex, System.Globalization.NumberStyles.HexNumber);

            //in this example 50000 is the 1st partition offset,



            //3. Get 2st partition offset
            //0x40028		03 E0 00 00  ->03E00000->1111100000000000000000->(<<2)->111110000000000000000000->(260046848d, 0F800000) <-2nd partition location
            //0x4002C		00 00 00 00  ->00000000-> 0 indicates a data partition
            int pito2Dec = pito1Dec + 8; //40020 + 8 = 40028
            

            string p2offset, p2offsetHex;
            FileStream fs104 = new FileStream(@path, FileMode.Open, FileAccess.Read);
            long offset104 = fs104.Seek(pito2Dec, SeekOrigin.Begin);   // Seek to pito2Dec byte in the file

            p2offset = "";
            p2offsetHex = "";

            x = 0;
            //this loop lets us grab bytes 327680 (4 bytes)
            while (x <= 3)
            {

                p2offset = fs104.ReadByte().ToString("X");
                if (p2offset.Length == 1)
                {
                    p2offset = "0" + p2offset;
                }

                //output the hex value
                p2offsetHex += p2offset;

                x++;

            }
            fs104.Close();


            //this is how we left shift 2 
            string p2offsetBinary = Convert.ToString(Convert.ToInt32(p2offsetHex, 16), 2);
            p2offsetBinary = p2offsetBinary + "00";

            //convert from binary back to hex to get the offset 
            string p2offsetFoundHex = Convert.ToString(Convert.ToInt32(p2offsetBinary, 2), 16);

            po2TextBox.Text = "0x" + p2offsetFoundHex;
            //put the offset to decimal form for seeking ??
            int p2offsetDec = int.Parse(p1offsetFoundHex, System.Globalization.NumberStyles.HexNumber);

            //in this example 0xF80000 is the 2nd partition offset,


            //now we need to get the type of partition, so move up 4 bytes and read that data
            int pito2DecType = pito2Dec + 4; //this should put us at 0x4002C


            string typeOfPart2Hex, typeOfPartHex2All;
            FileStream fs105 = new FileStream(@path, FileMode.Open, FileAccess.Read);
            long offset105 = fs105.Seek(pito2DecType, SeekOrigin.Begin);   // Seek to 262148 byte in the file
            typeOfPart2Hex = "";
            typeOfPartHex2All = "";
            x = 0;
            //this loop lets us grab 4 bytes to get the type of partition
            while (x <= 3)
            {
                typeOfPart2Hex = fs105.ReadByte().ToString("X");
                if (typeOfPart2Hex.Length == 1)
                {
                    typeOfPart2Hex = "0" + typeOfPart2Hex;
                }
                //this stores the hex value of the offset 262148 + 4bytes
                typeOfPartHex2All += typeOfPart2Hex; //hex string
                //partType1TextBox.Text = typeOfPartHexAll;
                x++;
            }
            fs105.Close();

            //define the partition type
            if (typeOfPartHex2All == "00000001")
            {
                partType2TextBox.Text = "1 (Update)";
            }
            else if (typeOfPartHex2All == "00000000")
            {
                partType2TextBox.Text = "0 (Data)";
            }
            else
            {
                partType2TextBox.Text = "? Unknown -> HEX Value:" + typeOfPartHex2All;
            }

        }
    }
}
